package com.ayoldi.podcastusbsync.configurator;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.apache.log4j.Logger;
import org.joda.time.DateTime;

import com.ayoldi.podcastusbsync.downloader.FeedsDownloaderThread;
import com.ayoldi.podcastusbsync.downloader.FeedsDownloaderUtils;
import com.ayoldi.podcastusbsync.model.Configuration;
import com.ayoldi.podcastusbsync.model.Configuration.GlobalOptions;
import com.ayoldi.podcastusbsync.model.Configuration.UsbDeviceConfiguration;
import com.ayoldi.podcastusbsync.model.Configuration.UsbDeviceConfiguration.PodcastFeed;
import com.ayoldi.podcastusbsync.synchronizer.USBDeviceCheckerThread;
import com.ayoldi.podcastusbsync.synchronizer.USBDeviceSynchronizer;

public class ConfigurationManager {

	static Logger LOG = Logger.getLogger(ConfigurationManager.class);
	
	File configFile;
	Configuration configuration;
	
	Unmarshaller jaxbUnmarshaller;
	Marshaller jaxbMarshaller;
	
	
	public ConfigurationManager(File configFile){
		this.configFile=configFile;	
		
		JAXBContext jaxbContext;
		try {
			jaxbContext = JAXBContext.newInstance(Configuration.class);
			jaxbMarshaller=jaxbContext.createMarshaller();
			jaxbMarshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE ); 
			jaxbUnmarshaller = jaxbContext.createUnmarshaller();
		} catch (JAXBException e) {
			e.printStackTrace();
			
		}
		
		readConfig(jaxbUnmarshaller);
		
	}
	
	private Configuration readConfig(Unmarshaller jaxbUnmarshaller) {

		try {
			configuration = (Configuration) jaxbUnmarshaller.unmarshal(configFile);
			LOG.info("Configuration loaded succesfully from file: "+configFile.getAbsolutePath());
		} catch (JAXBException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			LOG.warn("Could not load configuration from file: "+configFile.getAbsolutePath());
		}
		
		
		return configuration;
	}	
	
	public boolean writeConfig (Marshaller jaxbMarshaller) {
		synchronized (this){
			try {
				jaxbMarshaller.marshal(configuration, configFile);
				LOG.info("Configuration saved succesfully to file: "+configFile.getAbsolutePath());
				return true;
			} catch (JAXBException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				LOG.warn("Could not save configuration to file: "+configFile.getAbsolutePath());
				return false;
			}
		} 	
		
		
	}

	public GlobalOptions getGlobalOptions() {
		readConfig(jaxbUnmarshaller);
		return ConfigurationUtils.getGlobalOptions(configuration);
	}

	public List<UsbDeviceConfiguration> getUsbDeviceConfigurations() {
		readConfig(jaxbUnmarshaller);
		return ConfigurationUtils.getUsbDeviceConfigurations(configuration);
	}

	public List<PodcastFeed> getFeeds() {
		readConfig(jaxbUnmarshaller);
		return ConfigurationUtils.getFeeds(configuration);
	}

	public boolean updateLastCheckedTag(DateTime newLastCheckedDateTime, PodcastFeed feed) {
		
		readConfig(jaxbUnmarshaller);
		
		for (PodcastFeed currentFeed : this.getFeeds()){
			if (currentFeed.getName().equalsIgnoreCase(feed.getName())){
				currentFeed.setLastChecked(FeedsDownloaderUtils.formatDate(newLastCheckedDateTime));
				
			}
		}
		boolean success=writeConfig(jaxbMarshaller);
		if (success){
			LOG.info("Last checked parameter updated succesfully ("+feed.getLastChecked()+") for feed: "+feed.getName());
		}
		else{
			LOG.warn("Could not update last checked parameter ("+feed.getLastChecked()+") for feed: "+feed.getName());

		}		
		
		return success;
		
	}

	public File getLocalSyncFolder() {
		readConfig(jaxbUnmarshaller);
		return ConfigurationUtils.getLocalSyncFolder(configuration);
	}
	
	public Boolean getDeleteWhenSync(){
		readConfig(jaxbUnmarshaller);
		try{
			return Boolean.parseBoolean(getGlobalOptions().getDeleteWhenSync());
		}
		catch (Exception e){
			return false;
		}
	}

	public File getAbsoluteFeedDownloadFolder(String folder) {
		readConfig(jaxbUnmarshaller);
		return ConfigurationUtils.getAbsoluteFeedDownloadFolder(getLocalSyncFolder().getAbsolutePath(), folder);
	}

	public File getFeedUsbDeviceFolder(File deviceFolder, PodcastFeed feed) {
		readConfig(jaxbUnmarshaller);
		return ConfigurationUtils.getFeedUsbDeviceFolder(deviceFolder, feed);
	}
	
	
	
	

	
}
